﻿@page "/tgruntime/collectdevicevariable"
@namespace ThingsGateway.Web.Page
@using System.Linq.Expressions;
@using BlazorComponent;
@using Furion.DataValidation;
@using Furion;
@using Mapster;
@using Masa.Blazor.Presets;
@using System.IO;
@using TouchSocket.Core;
@attribute [Authorize]
@inject MasaBlazor MasaBlazor
@attribute [RolePermission]
@inherits CultureComponentBase
@implements IDisposable
@inject UserResoures UserResoures
@layout MainLayout

<MRow>
    <MCol Md=2 Cols="12">
        <MCard Class="ma-2" Style="height:100%">
            <MCardTitle>
                <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_searchName"
                            Outlined Label=@typeof(CollectDevice).GetDescription(nameof(CollectDevice.DeviceGroup)) />
                </MCardTitle>
                <MTreeview Dense TItem="DeviceTree" TKey="string"  Active="_searchModel.DeviceName?.StringToList()" OpenOnClick ActiveChanged=@((async a=>
                       {
                       if(this._searchModel.DeviceName!= a.FirstOrDefault())
                       {
                       this._searchModel.DeviceName= a.FirstOrDefault();
                       await datatableQuery();
                       }
                       }) )
                       Items="_deviceGroups" ItemText="r=>r.Name" ItemChildren="r=>r.Childrens"
                       Search="@_searchName"
                       Activatable ItemKey=@(r=>r.Name)>
            </MTreeview>
            </MCard>
            </MCol>
            <MCol Md=10 Cols="12">
            <div style="height: calc(100vh - 200px)">

<AppDataTable @ref="_datatable" TItem="CollectVariableRunTime" SearchItem="VariablePageInput"
              AddItem="object" EditItem="object"
              SearchModel="_searchModel"
              QueryCall="QueryCall"
              FilterHeaders="FilterHeaders" Filters="Filters" ShowDetailButton IsShowOperCol=true
                ShowQueryButton>
    <SearchTemplate>
        <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1  mx-2 " @bind-Value="context.Name" Clearable
                        Outlined Label=@context.Description(x => x.Name) />
        <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1  mx-2 " @bind-Value="context.DeviceName" Clearable
                        Outlined Label=@context.Description(x => x.DeviceName) />
    </SearchTemplate>

    <ItemColOperTemplate>
        <MButton Text Disabled=@(!UserResoures.IsHasButtonWithRole("tgcollectdeviceedit")) Class="my-1  mx-2" OnClick=@(() => Write(context.Item))>
            @T("写入")
        </MButton>
    </ItemColOperTemplate>
    <ItemColTemplate>
        @switch (context.Header.Value)
        {

            case nameof(context.Item.Quality):
                <EnableChip Value="context.Item.Quality==192" DisabledLabel=@context.Item.Quality.ToString() EnabledLabel=@context.Item.Quality.ToString()>
                </EnableChip>
                break;
            default:
                @context.Value
                break;

        }

    </ItemColTemplate>

</AppDataTable>

        </div>
    </MCol>
</MRow>

@code {
    string _searchName;
    List<DeviceTree> _deviceGroups = new();


    [Parameter]
    [SupplyParameterFromQuery]
    public string DeviceName { get; set; }

    VariablePageInput _searchModel { get; set; } = new();
    private IAppDataTable _datatable;
    CollectDeviceHostService CollectDeviceHostService { get; set; }
    private System.Timers.Timer DelayTimer;
    protected override async Task OnParametersSetAsync()
    {
        if (_searchModel.DeviceName != DeviceName)
        {
            _searchModel.DeviceName = DeviceName;
            await datatableQuery();
        }
        CollectDeviceHostService = this.GetBackgroundService<CollectDeviceHostService>();
        var data = CollectDeviceHostService.CollectDeviceCores.Select(a => a.Device).ToList();
        _deviceGroups = CollectDeviceService.GetTree(data.Adapt<List<CollectDevice>>());

        await base.OnParametersSetAsync();  
    }
    protected override async Task OnInitializedAsync()
    {
        DelayTimer = new System.Timers.Timer(1000);
        DelayTimer.Elapsed += timer_Elapsed;
        DelayTimer.AutoReset = true;
        DelayTimer.Start();
        await base.OnInitializedAsync();
    }
    async void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        await InvokeAsync(StateHasChanged);
    }
    public void Dispose()
    {
        DelayTimer.Dispose();
    }
    private async Task datatableQuery()
    {
        if (_datatable != null)
            await _datatable?.QueryClick();
    }
    [Inject]
    RpcCore rpcCore { get; set; }
    private async Task Write(CollectVariableRunTime collectVariableRunTime)
    {
        var confirm = await PopupService.PromptAsync(T("写入"),
        $"输入变量{collectVariableRunTime.Name}的写入值");
        if (confirm != null)
        {
            var data=   await rpcCore?.InvokeDeviceMethod($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString()}",  new NameVaue { Name = collectVariableRunTime.Name, Value = confirm  }, true);
            if(data.IsSuccess)
            {
                await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync(data.Message, AlertTypes.Success));
            }
            else
            {
                await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync(data.Message, AlertTypes.Warning));
            }
        }
    }

    private void FilterHeaders(List<DataTableHeader<CollectVariableRunTime>> datas)
    {
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.CreateUserId));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.UpdateUserId));

        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.IsDelete));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.ExtJson));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.Id));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.VariablePropertys));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.DeviceId));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.VariableValueChange));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.ThingsGatewayBitConverter));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.StringBcdFormat));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.DataType));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.EventTime));
        datas.RemoveWhere(it => it.Value == nameof(CollectVariableRunTime.EventTypeEnum));

        datas.RemoveWhere(it => it.Value.Contains("His"));
        datas.RemoveWhere(it => it.Value.Contains("Alarm"));
        datas.RemoveWhere(it => it.Value.Contains("RestrainExpressions"));

        foreach (var item in datas)
        {
            item.Sortable = false;
            item.Filterable = false;
            item.Divider = false;
            item.Align = DataTableHeaderAlign.Start;
            item.CellClass = " table-minwidth ";
            switch (item.Value)
            {
                case nameof(CollectVariableRunTime.Name):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.DeviceName):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.VariableAddress):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.OtherMethod):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.ChangeTime):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.Quality):
                    item.Sortable = true;
                    break;
                case nameof(CollectVariableRunTime.ReadExpressions):
                    item.Sortable = true;
                    break;
            }
        }
    }

    private void Filters(List<Filters> datas)
    {
        foreach (var item in datas)
        {
            switch (item.Key)
            {
                case nameof(CollectVariableRunTime.CreateTime):
                case nameof(CollectVariableRunTime.UpdateTime):
                case nameof(CollectVariableRunTime.CreateUser):
                case nameof(CollectVariableRunTime.UpdateUser):
                    item.Value = false;
                    break;
            }
        }
    }

    private async Task<SqlSugarPagedList<CollectVariableRunTime>> QueryCall(VariablePageInput input)
    {
        var devices = CollectDeviceHostService.CollectDeviceCores.SelectMany(it => it.Device.DeviceVariableRunTimes).ToList();
        var data = await devices
    .WhereIf(!input.DeviceName.IsNullOrEmpty(), a => a.DeviceName==input.DeviceName)
    .WhereIf(!input.Name.IsNullOrEmpty(), a => a.Name.Contains(input.Name)).ToList()
    .ToPagedListAsync(input);
        return data;


    }
}
